home *** CD-ROM | disk | FTP | other *** search
- -> JoyControl32
-
- ->>> Header (globals)
- MODULE 'amigalib/ports',
- 'amigalib/io',
- 'devices/gameport',
- 'devices/inputevent',
- 'devices/timer',
- 'exec/execbase',
- 'exec/io',
- 'exec/nodes',
- 'exec/ports',
- 'workbench/workbench',
- 'icon',
- 'wb',
- 'intuition/intuition',
- 'workbench/startup'
-
-
-
- ENUM ERR_NONE, ERR_DEV, ERR_IO, ERR_PORT,NOICONLIB,NOWBLIB, ERR_APPICON, ERR_DOBJ, ERR_LIB
-
-
- RAISE ERR_DEV IF OpenDevice()<>0,
- ERR_APPICON IF AddAppIconA()=NIL,
- ERR_DOBJ IF GetDefDiskObject()=NIL,
- ERR_LIB IF OpenLibrary()=NIL,
- ERR_PORT IF CreateMsgPort()=NIL
-
- CONST JOY_X_DELTA=1, JOY_Y_DELTA=1
-
- DEF exec:PTR TO execbase, cdresult, oldcdresult, rg:PTR TO wbarg, myargs:PTR TO LONG, wbm:PTR TO wbstartup,dir,
- pname,z[200]:STRING,string[200]:STRING, do:PTR TO diskobject, doapp:PTR TO diskobject,
- tenth_off_second,check_every, myport=NIL, appicon=NIL, appmsg:PTR TO appmessage, dropcount
-
- -> Allocate everything and go. On failure, free any resources that have been allocated.
- PROC main() HANDLE
- DEF joytrigger:gameporttrigger, game_io_msg=NIL:PTR TO iostd,
- game_msg_port=NIL, open_dev=FALSE
-
- VOID '$VER: Joy32 1.0 (9.2.99) sorenf@hem1.passagen.se'
- -> open the resources we need...
- workbenchbase:=OpenLibrary('workbench.library',37)
- IF (workbenchbase:=OpenLibrary('workbench.library',
- 37))=NIL THEN Raise(NOWBLIB)
-
-
-
- IF (iconbase:=OpenLibrary('icon.library',37))=NIL THEN Raise(NOICONLIB)
- myargs:=[0,0,0,0,0,0,0,0,0,0,0] -> static array for the arg's
- wbm:=wbmessage
- tenth_off_second:=exec.vblankfrequency/10
- -> compute program's path and name, i.e. get it from the wbmessage
- IF wbmessage
- IF wbm.numargs>0
- rg:=wbm.arglist+((wbm.numargs-1)*SIZEOF wbarg)
- dir:=CurrentDir(rg[].lock)
- pname:=rg.name
- ELSE
- pname:='progdir:joycon32'
- ENDIF
- ELSE
- pname:=StringF(string,'progdir:\s',GetProgramName(z,200) BUT z)
- ENDIF
- -> we must have an icon!
- IF do:=GetDiskObject(pname)
- myargs[0]:=FindToolType(do.tooltypes,'PLAY')
- myargs[1]:=FindToolType(do.tooltypes,'FFW')
- myargs[2]:=FindToolType(do.tooltypes,'RWD')
- myargs[3]:=FindToolType(do.tooltypes,'CD32_G')
- myargs[4]:=FindToolType(do.tooltypes,'CD32_Y')
- myargs[5]:=FindToolType(do.tooltypes,'FIRE1')
- myargs[6]:=FindToolType(do.tooltypes,'FIRE2')
- myargs[7]:=FindToolType(do.tooltypes,'UP')
- myargs[8]:=FindToolType(do.tooltypes,'DOWN')
- myargs[9]:=FindToolType(do.tooltypes,'LEFT')
- myargs[10]:=FindToolType(do.tooltypes,'RIGHT')
- myargs[11]:=FindToolType(do.tooltypes,'CHECK_EVERY')
-
- IF myargs[11] THEN check_every:=Val(myargs[11]) ELSE check_every:=1
- ELSE
- Raise(NIL)
- ENDIF
-
- -> This is a easy way to get some icon imagery altough not so elegant
-
- -> E-Note: get the right type for exec
- exec:=execbase
- -> Create port for gameport device communications
- IF NIL=(game_msg_port:=createPort('RKM_game_port', 0))
- Raise(ERR_PORT)
- ENDIF
- -> Create message block for device IO
- IF NIL=(game_io_msg:=createExtIO(game_msg_port, SIZEOF iostd))
- Raise(ERR_IO)
- ENDIF
-
- game_io_msg.mn.ln.type:=NT_UNKNOWN
- -> Open the right/back (unit 1, number 2) gameport.device unit
- OpenDevice('gameport.device', 1, game_io_msg, 0)
- open_dev:=TRUE
- -> Set controller type to joystick
- IF set_controller_type(GPCT_ABSJOYSTICK, game_io_msg)
- -> Specify the trigger conditions
- set_trigger_conditions(joytrigger, game_io_msg)
-
- -> WriteF('\n >>> JoyControl32 <<<\n\n')
- makeapp()
-
- -> Clear device buffer to start from a known state.
- -> There might still be events left.
- flush_buffer(game_io_msg)
-
- processEvents(game_io_msg, game_msg_port) -> MainLOOP
-
- -> Free gameport unit so other applications can use it!
- free_gp_unit(game_io_msg)
- ENDIF
- EXCEPT DO
- IF appicon THEN RemoveAppIcon(appicon)
- IF myport
- -> Clear away any messages that arrived at the last moment
- WHILE appmsg:=GetMsg(myport) DO ReplyMsg(appmsg)
- DeleteMsgPort(myport)
- ENDIF
- IF do THEN FreeDiskObject(do)
- IF workbenchbase THEN CloseLibrary(workbenchbase)
- IF iconbase THEN CloseLibrary(iconbase)
- IF open_dev THEN CloseDevice(game_io_msg)
- IF game_io_msg THEN deleteExtIO(game_io_msg)
- IF game_msg_port THEN deletePort(game_msg_port)
- SELECT exception
- CASE ERR_DEV; WriteF('Error: could not open gameport device\n')
- CASE ERR_IO; WriteF('Error: could not create I/O\n')
- CASE ERR_APPICON; WriteF('Error: Could not attach AppIcon to Workbench\n')
- CASE ERR_DOBJ; WriteF('Error: Could not get default icon\n')
- CASE ERR_LIB; WriteF('Error: Could not open required library\n')
- CASE ERR_PORT; WriteF('Error: Could not create port\n')
- ENDSELECT
- ENDPROC
-
-
- ->>> PROC check_move(game_event:PTR TO inputevent)
- -> Print out information on the event received.
- PROC check_move(game_event:PTR TO inputevent)
- DEF xmove, ymove, timeout=FALSE
- xmove:=game_event.x
- ymove:=game_event.y
-
- IF xmove=1
- IF ymove=1
- WriteF('RIGHT DOWN\n')
- ELSEIF ymove=0
- WriteF('RIGHT\n')
- action(10)
- ELSEIF ymove=-1
- WriteF('RIGHT UP\n')
-
- ELSE
- WriteF('UNKNOWN Y\n')
- ENDIF
- ELSEIF xmove=-1
- IF ymove=1
- WriteF('LEFT DOWN\n')
- ELSEIF ymove=0
- WriteF('LEFT\n')
- action(9)
- ELSEIF ymove=-1
- WriteF('LEFT UP\n')
- ELSE
- WriteF('UNKNOWN Y\n')
- ENDIF
- ELSEIF xmove=0
- IF ymove=1
- WriteF('DOWN\n')
- action(8)
- ELSEIF ymove=0
- -> Note that 0,0 can be a timeout, or a direction release.
- IF game_event.timestamp.secs >= (tenth_off_second*check_every)
- -> Under 1.3 (V34) and earlier versions of the Amiga OS, the
- -> timestamp.secs field used in the IF statement above is not
- -> correctly filled in. Therefore, this program cannot tell the
- -> difference between a release event and a timeout under 1.3 (release
- -> events will be reported as timeouts).
- -> WriteF('TIMEOUT\n')
- timeout:=TRUE
- ELSE
- WriteF('release\n')
- ENDIF
- ELSEIF ymove=-1
- WriteF('UP\n')
- action(7)
- ELSE
- WriteF('UNKNOWN Y\n')
- ENDIF
- ELSE
- WriteF('UNKNOWN X ')
- IF ymove=1
- WriteF('unknown action\n')
- ELSEIF ymove=0
- WriteF('unknown action\n')
- ELSEIF ymove=-1
- WriteF('unknown action\n')
- ELSE
- WriteF('UNKNOWN Y\n')
- ENDIF
- ENDIF
-
- checkcd32()
- actioncd32()
-
- ENDPROC timeout
- ->>>
-
- ->>> PROC send_read_request(game_event, game_io_msg:PTR TO iostd)
- -> Send a request to the gameport to read an event.
- PROC send_read_request(game_event, game_io_msg:PTR TO iostd)
- game_io_msg.command:=GPD_READEVENT
- game_io_msg.flags:=0
- game_io_msg.data:=game_event
- game_io_msg.length:=SIZEOF inputevent
- SendIO(game_io_msg) -> Asynchronous - message will return later
- ENDPROC
- ->>>
-
- ->>> PROC processEvents(game_io_msg:PTR TO iostd, game_msg_port:PTR TO mp)
- -> Simple loop to process gameport events.
- PROC processEvents(game_io_msg:PTR TO iostd, game_msg_port:PTR TO mp)
- DEF timeout, timeouts, button_count, not_finished, code,
- game_event:inputevent -> Where input event will be stored
- -> From now on, just read input events into the event buffer,
- -> one at a time. READEVENT waits for the preset conditions.
- timeouts:=0
- button_count:=0
- not_finished:=TRUE
-
- WHILE not_finished
-
- -> Send the read request
- send_read_request(game_event, game_io_msg)
- -> Wait for joystick action
- Wait(Shl(1, game_msg_port.sigbit))
- WHILE NIL<>GetMsg(game_msg_port)
- timeout:=FALSE
- code:=game_event.code
- SELECT code
- CASE IECODE_LBUTTON
- -> action(5)
- -> WriteF(' FIRE BUTTON PRESSED \n')
- CASE IECODE_LBUTTON OR IECODE_UP_PREFIX
- button_count++
- -> IF 3=button_count THEN not_finished:=FALSE
- CASE IECODE_RBUTTON
- -> action(6)
- -> WriteF(' ALT BUTTON PRESSED \n')
- button_count:=0
- CASE IECODE_RBUTTON OR IECODE_UP_PREFIX
- button_count:=0
- CASE IECODE_NOBUTTON
-
- -> Check for change in position
- timeout:=check_move(game_event)
- button_count:=0
- DEFAULT
- ENDSELECT
-
- IF timeout
- INC timeouts
- ELSE
- timeouts:=0
- ENDIF
- checkapp()
- ENDWHILE
- ENDWHILE
- ENDPROC
- ->>>
-
- ->>> PROC set_controller_type(type, game_io_msg:PTR TO iostd)
- -> Allocate the controller if it is available. You allocate the controller by
- -> setting its type to something other than GPCT_NOCONTROLLER. Before you
- -> allocate the thing you need to check if anyone else is using it (it is free
- -> if it is set to GPCT_NOCONTROLLER).
- PROC set_controller_type(type, game_io_msg:PTR TO iostd)
- DEF success=FALSE, controller_type_addr
- controller_type_addr:=[0]:CHAR
- -> Begin critical section.
- -> We need to be sure that between the time we check that the controller is
- -> available and the time we allocate it, no one else steals it.
- Forbid()
-
- game_io_msg.command:=GPD_ASKCTYPE -> Enquire current status
- game_io_msg.flags:=IOF_QUICK
- game_io_msg.data:=controller_type_addr -> Put answer in here
- game_io_msg.length:=1
- DoIO(game_io_msg)
-
- -> No one is using this device unit, let's claim it
- IF controller_type_addr[]=GPCT_NOCONTROLLER
- game_io_msg.command:=GPD_SETCTYPE
- game_io_msg.flags:=IOF_QUICK
- game_io_msg.data:=[type]:CHAR
- game_io_msg.length:=1
- DoIO( game_io_msg)
- success:=TRUE
- ENDIF
-
- Permit() -> Critical section end
- ENDPROC success
- ->>>
-
- ->>> PROC set_trigger_conditions(gpt:PTR TO gameporttrigger, game_io_msg:...)
- -> Tell the gameport when to trigger.
- PROC set_trigger_conditions(gpt:PTR TO gameporttrigger,
- game_io_msg:PTR TO iostd)
- -> Trigger on all joystick key transitions
- gpt.keys:=GPTF_UPKEYS OR GPTF_DOWNKEYS
- gpt.xdelta:=JOY_X_DELTA
- gpt.ydelta:=JOY_Y_DELTA
- -> Timeout trigger every check_every tenth off second
- -> gpt.timeout:=tenth_off_second*check_every
- gpt.timeout:=tenth_off_second*check_every
- game_io_msg.command:=GPD_SETTRIGGER
- game_io_msg.flags:=IOF_QUICK
- game_io_msg.data:=gpt
- game_io_msg.length:=SIZEOF gameporttrigger
- DoIO(game_io_msg)
- ENDPROC
- ->>>
-
- ->>> PROC flush_buffer(game_io_msg:PTR TO iostd)
- -> Clear the buffer. Do this before you begin to be sure you start in a known
- -> state.
- PROC flush_buffer(game_io_msg:PTR TO iostd)
- game_io_msg.command:=CMD_CLEAR
- game_io_msg.flags:=IOF_QUICK
- game_io_msg.data:=NIL
- game_io_msg.length:=0
- DoIO(game_io_msg)
- ENDPROC
- ->>>
-
- ->>> PROC free_gp_unit(game_io_msg:PTR TO iostd)
- -> Free the unit by setting its type back to GPCT_NOCONTROLLER.
- PROC free_gp_unit(game_io_msg:PTR TO iostd)
- DEF type=GPCT_NOCONTROLLER
- game_io_msg.command:=GPD_SETCTYPE
- game_io_msg.flags:=IOF_QUICK
- game_io_msg.data:=[type]:CHAR
- game_io_msg.length:=1;
- DoIO(game_io_msg)
- ENDPROC
- ->>>
-
-
-
- ->>>
- ->CD_PLAY EQU 1
- ->CD_RWD EQU 2
- ->CD_FFW EQU 3
- ->CD_G EQU 4
- ->CD_Y EQU 5
- ->CD_R EQU 6
- ->CD_B EQU 7
-
-
- ->;***********************************************************************
- ->;Reads CD 32 Controller
- ->;You must read joystick positions or button in normal way
- ->;BEFORE you call this.
- ->;One VBL MUST have elapsed before repeating this!
- PROC checkcd32()
- Forbid()
- ->ReadCD32:
- MOVEM.L D0-D2,-(A7) ->???
- MOVEM.L A0,-(A7) ->???
- BSET #7,$bfe201
- BCLR #7,$bfe001
- MOVE.W #$6f00,$dff034
- MOVEQ.L #0,D0
- MOVEQ.L #7,D1
- BRA.B gamecont4
-
- gamecont3:
- TST.B $bfe001
- TST.B $bfe001
- TST.B $bfe001
-
- gamecont4:
- TST.B $bfe001
- TST.B $bfe001
- TST.B $bfe001
- TST.B $bfe001
- TST.B $bfe001
- MOVE.W $dff016,D2
- BSET #7,$bfe001
- BCLR #7,$bfe001
- BTST #14,D2
- BNE.B gamecont5
- BSET D1,D0
-
- gamecont5:
- DBF D1,gamecont3
-
- BCLR #7,$bfe201
- MOVE.W #$ffff,$dff034
- LEA cdresult,A0 ->???
- MOVE.B D0,(A0)
- MOVEM.L (A7)+,A0 ->???
- MOVEM.L (A7)+,D0-D2 ->???
- Permit()
- ENDPROC
-
- PROC actioncd32()
- IF oldcdresult=0
- IF cdresult = 33554432 THEN action(0) -> CD_PLAY
- IF cdresult = 134217728 THEN action(1) -> CD_FFW
- IF cdresult = 67108864 THEN action(2) -> CD_RWD
- IF cdresult = 268435456 THEN action(3) -> CD_G
- IF cdresult = 536870912 THEN action(4) -> CD_Y
- IF cdresult = 1073741824 THEN action(5) -> CD_R *** Same as FIRE1, we use that instead.
- IF cdresult = -2147483648 THEN action(6) -> CD_B *** Same as FIRE2, we use that instead.
- ENDIF
- oldcdresult:=cdresult
- ENDPROC
-
- PROC action(button)
- IF myargs[button] THEN Execute (myargs[button],0,NIL)
- ENDPROC
-
-
- PROC checkapp()
- -> Might be more than one message at the port...
- WHILE appmsg:=GetMsg(myport)
- INC dropcount
- IF appmsg.numargs=0
- -> If numargs is 0 the AppIcon was activated directly
- Raise(NIL)
- ENDIF
- -> Let Workbench know we're done with the message
- ReplyMsg(appmsg)
- ENDWHILE
- ENDPROC
-
-
- PROC makeapp()
- Execute ('rename env:sys/def_disk.info env:sys/org_def_disk.info ',0,NIL)
- Execute ('copy JCapp.info env:sys/def_disk.info',0,NIL)
- doapp:=GetDefDiskObject(WBDISK) ->ENV:sys/def_disk.info
- -> The type must be set to NIL for a WBAPPICON
- doapp.type:=NIL
- -> The CreateMsgPort() function is in Exec version 37 and later only
- myport:=CreateMsgPort()
- -> Put the AppIcon up on the Workbench window
- appicon:=AddAppIconA(0, 0, 'JoyControl32', myport, NIL, doapp, NIL)
- Execute ('delete env:sys/def_disk.info',0,NIL)
- Execute ('rename env:sys/org_def_disk.info env:sys/def_disk.info ',0,NIL)
- ENDPROC